package utils

import (
    "bytes"
    "encoding/json"
    "io"
    "io/ioutil"
    "net/http"
    urlpkg "net/url"
    "strings"

    "git.inspur.com/x/common/loggerfactory"
    "git.inspur.com/x/common/rest"
)

var logger = loggerfactory.GetLogger()

func HttpReq(url, token, method string, body io.Reader, header http.Header) ([]byte, error) {

    urlInfo, err := urlpkg.Parse(url)
    if err != nil {
        logger.Error("parse err: %v\n", err)
        return nil, err
    }
    query, err := urlpkg.ParseQuery(urlInfo.RawQuery)
    if err != nil {
        logger.Error("ParseQuery err: %v\n", err)
        return nil, err
    }
    path := urlInfo.Path
    if urlInfo.RawPath != "" {
        path = urlInfo.RawPath
    }
    restConfig := rest.Config{
        Host:    urlInfo.Scheme + "://" + urlInfo.Host,
        APIPath: path,
    }
    restConfig.Insecure = true
    restClient, err := rest.RESTClientFor(&restConfig)
    if err != nil {
        logger.Error("RESTClientFor err: %v\n", err)
        return nil, err
    }
    var resp = ""
    var request *rest.Request
    switch method {
    case http.MethodGet:
        request = restClient.Get()
    case http.MethodDelete:
        request = restClient.Delete()
    case http.MethodHead:
        request = restClient.Head()
    case http.MethodPost:
        request = restClient.Post()
    case http.MethodPut:
        request = restClient.Put()
    }

    logger.Info("url: ", url)
    if !strings.Contains(url, "api/v1/buckets") {
        // 如果 url 中同时包含 AWSAccessKeyId 和 Signature 这两个字段，说明是直接下载的url，不需要添加这两个 header
        if !(strings.Contains(url, "AWSAccessKeyId") && strings.Contains(url, "Signature")) {
            request = request.SetHeader("Authorization", token)
            if body != nil {
                bodyByte, _ := ioutil.ReadAll(body)
                request = request.Body(ioutil.NopCloser(bytes.NewReader(bodyByte)))
                if json.Valid(bodyByte) {
                    request = request.SetHeader("Content-Type", "application/json")
                }
            }
        }
    }
    if header != nil {
        for k, v := range header {
            request = request.SetHeader(k, v[0])
        }
    }
    for key, value := range query {
        request = request.Param(key, value[0])
    }
    err = request.Do().Into(&resp)
    if err != nil {
        _ = logger.Error("Client.Do error %v", err)
        return []byte{}, err
    }
    return []byte(resp), nil
}
